/**
 * 
 */
package org.acompanhamento.pages.taskboard;

import static jmine.tec.web.wicket.pages.ResourceReferenceUtils.getCSSResource;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jmine.tec.di.annotation.Injected;
import jmine.tec.web.wicket.pages.Template;

import org.acompanhamento.HelpMessages;
import org.acompanhamento.dao.SprintDAO;
import org.acompanhamento.dao.StatusTransictionDAO;
import org.acompanhamento.dao.TaskDAO;
import org.acompanhamento.domain.Sprint;
import org.acompanhamento.domain.Status;
import org.acompanhamento.domain.Task;
import org.acompanhamento.domain.Team;
import org.acompanhamento.domain.Workflow;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.PropertyModel;

import bancosys.tec.exception.MessageCreator;
import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.security.annotation.Secure;
import bancosys.tec.security.authorization.UrlPermission;

/**
 * @author icaro
 *
 */
@Secure(id = "GENERIC_TEAM_MEMBER_URL", permissionType = UrlPermission.class)
public class TaskBoard extends Template {

	private Team team;

	private Sprint sprint;

	private final List<Status> statuses = new ArrayList<Status>();

	private final Map<Status, List<Task>> statusTasksMap = new HashMap<Status, List<Task>>();

	@Injected
	private BaseDAO<Team> teamDAO;

	@Injected
	private SprintDAO sprintDAO;

	@Injected
	private TaskDAO taskDAO;

	@Injected
	private StatusTransictionDAO statusTransictionDAO;

	@Override
	protected void onInitialize() {
		super.onInitialize();
		this.add(new FeedbackPanel("feedback").setOutputMarkupId(true));

		this.add(new WebMarkupContainer("containerTaskBoard").add(this.createStatusTasksListView()).add(this.createStatusListView()).setOutputMarkupId(true));

		// TODO adicionar a equipe do usuário como default na tela
		List<Team> teams = this.teamDAO.findAll();

		final DropDownChoice<Sprint> dropDownSprint = new DropDownChoice<Sprint>("sprint", new PropertyModel<Sprint>(this, "sprint"), new ArrayList<Sprint>());
		dropDownSprint.add(new AjaxFormComponentUpdatingBehavior("onchange"){
			@Override
			protected void onUpdate(AjaxRequestTarget target) {
				TaskBoard.this.updateStatusesTasks();
				TaskBoard.this.updateListView(target);
			}

		});
		this.add(dropDownSprint);

		DropDownChoice<Team> dropDownTeam = new DropDownChoice<Team>("team", new PropertyModel<Team>(this, "team"), teams);
		dropDownTeam.add(new AjaxFormComponentUpdatingBehavior("onchange") {

			@Override
			protected void onUpdate(AjaxRequestTarget target) {
				List<Sprint> sprints = TaskBoard.this.sprintDAO.findByTeam(TaskBoard.this.team);
				dropDownSprint.setChoices(sprints);
				if(!sprints.isEmpty()){
					TaskBoard.this.setSprint(sprints.get(0));
					TaskBoard.this.updateStatusesTasks();
				}
				target.add(dropDownSprint);
				TaskBoard.this.updateListView(target);
			}
		});
		this.add(dropDownTeam);
	}

	private void updateListView(AjaxRequestTarget target) {
		((WebMarkupContainer)TaskBoard.this.get("containerTaskBoard")).addOrReplace(TaskBoard.this.createStatusTasksListView()).addOrReplace(this.createStatusListView());
		target.add(TaskBoard.this.get("containerTaskBoard"));
	}

	private void updateStatusesTasks() {
		Workflow workflow = this.sprint.getWorkflow();
		Status status = workflow.getInitialStatus();
		this.statuses.clear();
		while(status != null){
			TaskBoard.this.statuses.add(status);
			List<Task> tasksByStatus = this.sprint.getTasksByStatus(this.taskDAO, status);
			this.statusTasksMap.put(status, tasksByStatus);
			status = workflow.getNextStatus(this.statusTransictionDAO, status);
		}
	}

	private Component createStatusListView() {
		return new ListView<Status>("statuses", this.statuses) {

			@Override
			protected void populateItem(ListItem<Status> item) {
				item.add(AttributeModifier.replace("width", 100F / TaskBoard.this.statuses.size() + "%"));
				item.add(new Label("status", item.getModelObject().getName()));
			}
		};
	}

	private Component createStatusTasksListView() {
		return new ListView<Status>("statusesTasks", this.statuses) {

			@Override
			protected void populateItem(ListItem<Status> item) {
				item.add(new ListView<Task>("tasks", TaskBoard.this.statusTasksMap.get(item.getModelObject())) {

					@Override
					protected void populateItem(ListItem<Task> item) {
						item.add(new Label("task", item.getModelObject().getSummary()));
					}
				});
			}
		};
	}

	@Override
	public void renderHead(IHeaderResponse response) {
		super.renderHead(response);
		response.renderCSSReference(getCSSResource("taskboard.css"));
	}

	/**
	 * @return the team
	 */
	public Team getTeam() {
		return this.team;
	}

	/**
	 * @return the sprint
	 */
	public Sprint getSprint() {
		return this.sprint;
	}

	/**
	 * @param team the team to set
	 */
	public void setTeam(Team team) {
		this.team = team;
	}

	/**
	 * @param sprint the sprint to set
	 */
	public void setSprint(Sprint sprint) {
		this.sprint = sprint;
	}

	@Override
	protected MessageCreator getHelpTextCreator() {
		return HelpMessages.TASKBOARD;
	}

}
